<template>
  <div class="h-wrap-tiptap">
    <div class="menu-wrap" v-if="editor">
      <button
        :class="{ 'is-active': editor.isActive('bold') }"
        @click="editor.chain().focus().toggleBold().run()"
      >
        加粗
      </button>
      <button @click="logJson">打印文档json</button>
      <button @click="logHTML">打印文档html</button>
      <button @click="logSchema">打印文档schema</button>
      <button @click="setH1">setH1</button>
      <button @click="setAttr">修改 attr</button>
    </div>
    <EditorContent :editor="editor" class="h-wrap-tiptap-content" />
  </div>
</template>
<script>
import { Editor, EditorContent } from "@tiptap/vue-2";
import { StarterKit } from "@tiptap/starter-kit";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import Bold from "@tiptap/extension-bold";
import BulletList from "@tiptap/extension-bullet-list";
import { ListItem, ListItemOptions } from '@tiptap/extension-list-item'
import Heading from "@tiptap/extension-heading";


import { Extension,mergeAttributes ,Node} from "@tiptap/core";
import { Plugin, PluginKey } from '@tiptap/pm/state';
import { Decoration, DecorationSet } from '@tiptap/pm/view';
import {DrawExtension} from '../render4/plugin/DrawExtension.js';
const CustomProsemirrorPluginExtension = Node.create({
  name: 'custom-hearding-color',
  priority: 1000,
  content:'inline*',
  group:'block',
  addOptions(){
    return{
      levels:[1,2,3,4,5,6],
      HTMLAttributes:{}
    }
  },
  addAttributes(){
    return{
      color:{
        default:'red'
      },
      level:{
        default:1
      }
    }
  },
  parseHTML(){
    console.log('parse heading ')
    console.log(this.options.levels)
    // return this.options.levels.map((level)=>{
      console.log('parse heading  parseHTML')
      return [{
        tag:`h${1}`,
        attrs:{
          color:'red',
          // level: level
        }
      }]
    // })
  },
  renderHTML({node,HTMLAttributes}){
    console.log('render heading  renderHTML')
 const colorStyle = HTMLAttributes.color && HTMLAttributes.color !== 'red' 
      ? `color: ${HTMLAttributes.color};font-size: 24px` 
      : 'color: red';
    return[
      `h${HTMLAttributes.level}`,
      mergeAttributes(this.options.HTMLAttributes,HTMLAttributes,{
        style:colorStyle
      }),
      0
    ]
  },
  // addNodeView() {
  //   console.log('render heading  addNodeView')
    
  //   return () => {
  //     console.log('render heading  addNodeView')
  //     const container = document.createElement("div");

  //     container.addEventListener("click", (event) => {
  //       alert("点击了容器");
  //     });

  //     const content = document.createElement("div");
  //     container.append(content);

  //     return {
  //       dom: container,
  //       contentDOM: content,
  //     };
  //   };
  // },
  addProseMirrorPlugins(){
    console.log('render heading  addProseMirrorPlugins');
    
    return[
      new Plugin({
        key:new PluginKey('custom-heading-color-prosemirror-test'),
        props: {
          handleKeyDown(view, event) {
            console.log('custom-heading-color-prosemirror-test',view,event)
            // return false
          },
          handleClick(view, event) {
            console.log('custom-heading-color-prosemirror-test',view,event)
            console.log("event",event)
            // return false
          },
        },
      }),  
      new Plugin({
        key: new PluginKey('selectionExtendKey'),
        props: {
          decorations(state,view) {
            // 没有 view 参数
            console.log('selectionExtendKey',this,state,view)
            if (state.selection.empty) {
              return null;
            }
            if (state.selection.from && state.selection.to) {
              return DecorationSet.create(state.doc, [
                Decoration.inline(state.selection.from, state.selection.to, {
                  class: 'hussar-word-text-selection',
                }),
              ]);
            }
          },
        },
      }),
    ]
  }
})
const CustomExtension = Extension.create({
  name: 'customExtension',
  addStorage() {
    return {
      count: 100,
    }
  },
  //   addProseMirrorPlugins(){
  //   return[
  //     new Plugin({
  //       key:new PluginKey('custom-aaaa'),
  //       props: {
  //         handleKeyDown(view, event) {
  //           console.log('custom-heading-color-prosemirror-test',view,event)
  //           // return false
  //         },
  //         handleClick(view, event) {
  //           console.log('custom-heading-color-prosemirror-test',view,event)
  //           // return false
  //         },
  //       },
  //     }),
  //   ]
  // },
  onUpdate(e) {
    // console.log(e)
    // this.storage.count++
    // console.log(this.storage.count)
    // console.log('========')
    // console.log('this.editor',this.editor)
    // console.log('this.name',this.name)
    // console.log('this.options',this.options)
    // console.log('this.parent',this.parent)

    // console.log('========')

  }
})
const TextAlign = Extension.create({
  name: 'textAlign',
  addGlobalAttributes(){
    return[
      {
        types:['paragraph','heading'],
        attributes:{
          textAlign:{
            default:null,
            renderHTML: (attrs) => {
              // console.log(attrs)
              return {
                style: `text-align: ${attrs.textAlign}`,
              }
            },
            parseHTML: (element) => {
              console.log(element)
              console.log(element.style)
              return element.style.textAlign||'left'
            }
          }
        }
      }
    ]
  }
})

const CustomBold = Bold.extend({
  priority: 1000,
  inline: false,
  renderHTML({ HTMLAttributes }) {
    return ['b', HTMLAttributes, 0]
  },
  addAttributes() {
    return {
      class: {
        default: 'custom-bold',
      },
      color: {
        rendered:true,
        default: null,
        // renderHTML: (attrs) => {
        //   console.log(attrs)
        //   // if (!attrs.color) {
        //   //   return {}
        //   // }
        //   return {
        //     style: `color: ${attrs.color||'red'}`,
        //   }
        // },
        // parseHTML: (element) => {
        //   console.log(element.style)
        //   return element.style.color||'red'
        // },
        parseHTML: (element) => {
          console.log(element)
          console.log(element.getAttribute('data-color'))
          console.log('this.editor',this.editor)
          return element.getAttribute('data-color')
        },
        renderHTML: (attrs) => {
          console.log(attrs)
          return {
            style: `color: ${attrs.color||'red'}`,
            'data-color': attrs.color || 'red',
          }
        },
      }
    }
  }
})


export default {
  name: "tiptap",
  components: {
    EditorContent,
  },
  data() {
    return {
      editor: null,
    };
  },
  mounted() {
    this.editor = new Editor({
      editorProps: {
        attributes: {
          class: 'focus-outline',
        }
      },
      // extensions: [
      //   StarterKit.configure({
      //     heading: {
      //       levels: [1, 2],
      //       HTMLAttributes: {
      //         class: "heading-cade",
      //       },
      //     },
      //   }),
      // ],
        extensions: [
          Document,
          Paragraph,
          Text,
          // Heading.configure({ levels: [1, 2] }),
          Bold,
         DrawExtension,
          // BulletList.configure({
          //   addKeyboardShortcuts() {
          //     return {
          //       // 没起作用，后续研究吧
          //       'Mod-shift-x': () => {
          //         console.log('Mod-shift-b')
          //         this.editor.commands.toggleHeading()
          //         return true
          //       },
          //     }
          //   },
          //   HTMLAttributes: {
          //     class: 'bullet-list',
          //   },
          // }),
          //  ListItem,
          // ListItemOptions,
          // CustomBold,
          CustomExtension,
          // TextAlign,
          CustomProsemirrorPluginExtension
        ],
      content:
        `<h1 level="1" color="blue">vue2 的 tiptap demo</h1>
        <h1 style="text-align: center;color:red;">vue2 的 tiptap demo</h1>
        <h2>vue2 的 tiptap demo</h2>
        <p>vue2 的 tiptap demo <strong  data-color='blue'>加粗</strong></p>
        <p style="font-weight: 600;">vue2 的 tiptap demo <em>斜体</em></p>
        `,
      autofocus: true,
      editable: true,
      injectCSS: false,
      onUpdate({ editor, transaction }) {
        console.log('onUpdate', editor, transaction)
      },
    });
      // 验证插件是否注册
  console.log('编辑器实例:', this.editor);
  console.log('注册插件:', this.editor.view.state.plugins);
  },
  beforeDestroy() {
    this.editor.destroy();
    this.editor = null;
  },
  methods: {
    logJson() {
      console.log(this.editor.getJSON());
      // 打印自定义扩展的count
      console.log(this.editor.storage.customExtension.count)
    },
    logHTML() {
      console.log(this.editor.getHTML());
    },
    logSchema() {
      console.log(this.editor.schema)
    },
    setH1(){
      this.editor.commands.setContent(`<h1 level="1" color="blue"> set vue2 的 tiptap demo</h1>
        <h1 style="text-align: center;color:red;">set vue2 的 tiptap demo</h1>
        <h2>vue2 的 tiptap demo</h2>
        <p>vue2 的 tiptap demo <strong  data-color='blue'>加粗</strong></p>
       
        `)
    },
    setAttr(){
      const { tr } = this.editor.state;

      const doc =   this.editor.state.doc
        const node =  doc.content.content[0]
        // node.attrs.level=3
        // node.attrs.color='red'
        console.log('修改了 node attrs')

        tr.setNodeAttribute(0, 'level', 3)
        tr.setNodeAttribute(0, 'color', 'red')
        this.editor.view.dispatch(tr);
        // 遍历节点
        // doc.descendants((node) => {
        //   console.log(node)
        // })
    }
  },
};
</script>
<style scoped lang="scss">
.h-wrap-tiptap {
  border: 1px solid #ccc;
  padding: 16px;
  height: 500px;
}
.h-wrap-tiptap-content {
  height: 100%;
}
.menu-wrap {
  border: 1px solid #ccc;
  display: flex;
  button {
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    color: #585858;
    margin: 8px;
  }
  .is-active {
    background-color: #42b983;
    color: #fff;
  }
}
.h-wrap-tiptap {
  :deep(.focus-outline) {
    border: 1px solid #ccc;
    &:focus {
      outline: none;
      border: 1px solid #42b983;
    }
  }
  :deep(.tiptap) {
    padding: 16px;
    .heading-cade {
      color: cadetblue;
    }
    p {
      font-size: 16px;
      margin: 16px 0;
    }
    .hussar-word-text-selection{
      background-color: rgb(253, 3, 37);
    }
   
  }
}
</style>
